/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.arif.alg.sulamunnayirain;





/**
 *
 * @author fii
 */
public class SulamunNayyirain {
	public static final int KEY_SUB = 0;
    public static final int KEY_SUD = 1;
    public static final int KEY_KHUM = 2;
    public static final int KEY_BUK = 3;
    public static final int KEY_LUTS = 4;
    public static final int KEY_SAWANI = 5;
    public static final int KEY_DEQIQOH = 6;
    public static final int KEY_SAAH = 7;
    public static final int KEY_AYYAM = 8;
    
    private final static int BANYAK_KOLOM_TABLE4 =12;
    private final static int BANYAK_KOLOM_TABLE6 =24;
    private final static int BANYAK_KOLOM_TABLE5 =24;
	private Row total;
	private Row takdilKhosoh;
	private Row takdilMarkaz;
	private Row albuduGhairuMuaddal3;
	private Row takdilSyams6;
	private Row muqowamusSyams6;
	private Row takdilAyam;
	private Row albukdulMuaddal6;
	private Row takdilAlamah10;
	private Row alamahJakarta6;
	private Row saatulIjtima6;
	private Row adadusSaah5;
	private Row irtifaulHilal6;
	private Row muktsulHilal7;
	private Row hisotusSaah6;
	
    public Row getHisotusSaah6() {
		return hisotusSaah6;
	}

	private Row getTakdil(int table, Row total, int banyakKolom, int[] limitTakdil, int derajat, int buruj, int kali, int maxRow) throws Exception{
        int satar_awal=TableConstant.getInstance().getTable(table, derajat, buruj);
        int jaah_awal = TableConstant.getInstance().getTable(table, derajat, buruj+1);
        if(derajat>=maxRow){
            derajat=0;
        }else{
            derajat+=1;
        }
        int satar_tsani=TableConstant.getInstance().getTable(table, derajat, buruj);
        int jaah_tsani=TableConstant.getInstance().getTable(table, derajat, buruj+1);
        int alfadlu = Math.abs(satar_awal-satar_tsani);
        
        int hasilKali= kali * alfadlu;
                
        Kotak kotak=new Kotak();
        kotak.set(hasilKali, 60);
        
        Row takdilAtas = new Row(3);
        Row takdilBawah = new Row(3);
        Row takdil =new Row(3);
        
        takdilAtas.set(1, satar_awal);
        takdilBawah.set(1, kotak.lebih);
                
        takdilAtas.set(0, 0);
        takdilBawah.set(0, kotak.sisa);
        
        takdilAtas.set(2, jaah_awal);
        takdilBawah.set(2, 0);
                
        if(satar_awal<satar_tsani){
            takdil = takdilAtas.add(takdilBawah, limitTakdil, false, 3);
        }else{
            takdil = takdilAtas.substract(takdilBawah, limitTakdil, false, 3);
        }
                
        return takdil;
    }
            
    public Record process(int year, int monthBefore, int kota) throws Exception{
       String syear=year+"";
       char k=syear.charAt(3);
       String akhir=k+"";       
       int majmuah=new Integer(akhir).intValue();
       int mabsuthoh=year-majmuah;
       return this.process(mabsuthoh, majmuah, monthBefore, kota);
   }
    final String log_tag = "fikry_process";
	
    public Record process(int majmuah, int mabsuthoh, int monthBefore, int kota) throws Exception{
    	//Log.w(log_tag, "process firstly "+majmuah+ " "+mabsuthoh+" "+monthBefore+" "+kota);
        Row rowMajmuah=TableConstant.getInstance().getTable(1, majmuah);
        //Log.w(log_tag, "rowMajmuah table 1");
        Row rowMonth=TableConstant.getInstance().getTable(3, monthBefore);
        //Log.w(log_tag, "rowMonth table 3");
        int[] limit={60,30,12,60,30,12,60,30,12,60,30,12,60,24,7};        
        if(mabsuthoh > 0){
        	//Log.w(log_tag, "rowMabsuthoh table 2");
        	Row rowMabsuthoh = TableConstant.getInstance().getTable(2, mabsuthoh);
        	total = rowMajmuah.add(rowMabsuthoh, limit, false, 3).add(rowMonth, limit, false, 3);
        }else{
        	total = rowMajmuah.add(rowMonth, limit, false, 3);
        }
        //Log.w(log_tag, "mencari total");
        int derajat;        
        int buruj;
        int kali;
        int[] limitTakdil= {60,60,30};
        hisotusSaah6 = new Row(6);
        // --------------------- Takdil khosoh --------------------------- //
        
        derajat = total.get(7);        
        buruj = BANYAK_KOLOM_TABLE6 -((total.get(8) +1)*2);
        kali=total.get(6);        
        takdilKhosoh = getTakdil(6, total, BANYAK_KOLOM_TABLE6, limitTakdil, derajat, buruj, kali, 29);        
        //Log.w(log_tag, "takdil khosoh");
        // --------------------- Takdil markaz --------------------------- //
        
        derajat = total.get(4);        
        buruj = BANYAK_KOLOM_TABLE6 -((total.get(5) +1)*2);
        kali = total.get(3);
        takdilMarkaz = getTakdil(5, total, BANYAK_KOLOM_TABLE5, limitTakdil, derajat, buruj, kali, 29);
        //Log.w(log_tag, "Takdil markaz");
        // ------------- Bu'dhu Ghoiru Mua'adal ----------------------- //
        
        albuduGhairuMuaddal3 = takdilMarkaz.add(takdilKhosoh, limitTakdil, false, 3);
        //Log.w(log_tag, "Bu'dhu Ghoiru Mua'adal");
        // ------------- Takdil Syams ----------------------- //
        
        int[] limitTakdilSyams={60,60,60,60,60,60};    
        int[] limitTakdilSyams3 = {60,60,60};
        Row[] rowTm = new Row[3];
        Row hasilKaliGhoiruMuadal3 = new Row(3);
            for(int i=0;i<3;i++){
                rowTm[i] = new Row(3);
                rowTm[i].set(i, 5 * albuduGhairuMuaddal3.get(i));
                rowTm[i] = rowTm[i].normalize(limitTakdilSyams3, false, 3);
                hasilKaliGhoiruMuadal3 = hasilKaliGhoiruMuadal3.add(rowTm[i], limitTakdilSyams3, false, 3);
            }
        takdilSyams6 = new Row(6);             
        for(int i=0;i<3;i++){
            takdilSyams6.set(2+i, hasilKaliGhoiruMuadal3.get(i));     
        }
        Row takdilMarkaz6=new Row(6);
        takdilMarkaz6.set(5, takdilMarkaz.get(2));
        takdilMarkaz6.set(4, takdilMarkaz.get(1));
        takdilMarkaz6.set(3, takdilMarkaz.get(0));        
        takdilSyams6=takdilSyams6.add(takdilMarkaz6, limitTakdilSyams, false, 6);
        //Log.w(log_tag, "Takdil Syams");
        // ------------- Wassatus Syams----------------------- //
        
        Row rowAuj=total.getPerFragment(0, 3);
        Row rowMarkaz=total.getPerFragment(3, 3);
        int[] limitWasatusSyams = {60,30,12};
        int yy = rowAuj.length;
        int ook = rowMarkaz.length;
        Row wassatusSyams = rowAuj.add(rowMarkaz, limitWasatusSyams, false, 3);
        
        // convert to 6 coloumns
        Row wassatusSyams6 = new Row(6);
        wassatusSyams6.set(5, wassatusSyams.get(2));
        wassatusSyams6.set(4, wassatusSyams.get(1));
        wassatusSyams6.set(3, wassatusSyams.get(0));
        
     // ------------- Muqowwamus Syams----------------------- //
        int[] limitMuqowamusSyams = {60,60,60,60,30,12};
        // geser takdilus syams
        takdilSyams6.move(1, true);
                
        muqowamusSyams6 = wassatusSyams6.substract(takdilSyams6, limitMuqowamusSyams, false, 6);
        //Log.w(log_tag, "Muqowwamus Syams");
        // ------------- Takdil Ayyam ----------------------- //
        
        buruj = muqowamusSyams6.get(5);
        derajat=0;
        int jahMuqowwamus=muqowamusSyams6.get(4);
        if(jahMuqowwamus>=25){
            derajat=25;
        }else if(jahMuqowwamus>=20){
            derajat=20;
        }else if(jahMuqowwamus>=15){
            derajat=15;
        }else if(jahMuqowwamus>=10){
            derajat=10;
        }else if(jahMuqowwamus>=5){
            derajat=5;
        }else{
            derajat=0;
        }
        
        int satarAtas=TableConstant.getInstance().getTable(4, derajat, Math.abs(buruj-11));
        int satarBawah=TableConstant.getInstance().getTable(4, (derajat>=25?0:derajat+5), Math.abs(buruj-11));        
        int deqiqoh=Math.abs(satarAtas-satarBawah);
        int sawani=(deqiqoh*60)/5;
        rowTm = new Row[2];        
        int[] limitAyam= {60,60,30};
        Row hasilKali = new Row(3);
        takdilAyam = new Row(3);
        Row muqowamusSyams3 = muqowamusSyams6.getPerFragment(3, 3);
        for(int i=0;i<2;i++){
            rowTm[i] = new Row(3);            
        }
        int ms = muqowamusSyams3.get(1);
        rowTm[0].set(0, sawani * ms);
        rowTm[0] = rowTm[0].normalize(limitAyam, false, 3);            
        
        ms = muqowamusSyams3.get(0);        
        rowTm[1].set(1, sawani * ms);
        rowTm[1] = rowTm[1].normalize(limitAyam, false, 3);            
        
        hasilKali = hasilKali.add(rowTm[1], limitAyam, false, 3);
        hasilKali = hasilKali.add(rowTm[0], limitAyam, false, 3);
        
        Row rowI= new Row(3);
        rowI.set(2, satarAtas);
        if(satarAtas>satarBawah){
            takdilAyam = rowI.substract(hasilKali, limitAyam, false, 3);
        }else{
            takdilAyam = rowI.add(hasilKali, limitAyam, false, 3);
        }
        //Log.w(log_tag, "Takdil Ayyam");
        /************************ Al-Bukdul Muaddal ****************************/
                
        // convert to 6 columns        
       Row albuduGhairuMuaddal6 = new Row(6);
       albuduGhairuMuaddal6.convertWith(albuduGhairuMuaddal3, 3);        
       Row takdilAyam6 = new Row(6);
       takdilAyam6.convertWith(takdilAyam, 2);        
       int[] limitAlbukdulMuadal = {60,60,60,60,60,30};
       albukdulMuaddal6 = albuduGhairuMuaddal6.substract(takdilAyam6, limitAlbukdulMuadal, false, 6);
       //Log.w(log_tag, "Al-Bukdul Muaddal");
       /************************ Takdil Hissotus Sa'ah ****************************/
       //buruj = total.get(8);
       //derajat = total.get(7);
       //revisi 24 januari 2015
       buruj = total.get(8);
       derajat = total.get(7);
       
       Row rowSatarAwal = TableConstant.getInstance().getTable7(derajat, buruj);
       int indexHisotusSaah = 14;
       if(buruj>=6 && derajat>0){
    	   derajat-=5;
    	   indexHisotusSaah = 2;
       }else{
    	   derajat+=5;   
       }
       
       if(derajat>25){
           derajat=0;
           buruj++;
       }
       if(buruj==0 && derajat==6){
           buruj=0;
           derajat=0;
       }
       Row rowSatarSani = TableConstant.getInstance().getTable7(derajat, buruj);
       
       Row awal2 = rowSatarAwal.getPerFragment(indexHisotusSaah, 2);
       Row sani2 = rowSatarSani.getPerFragment(indexHisotusSaah, 2);
       satarAtas  = awal2.get(0);
       satarBawah = sani2.get(0);
       
       int[] limit2 ={60,60};
       Row total2 = awal2.substract(sani2, limit2, false, 2);
       sawani = (total2.get(0) * 60)  / 5 ;
       if(sawani==0){
            hisotusSaah6.set(5, awal2.get(1));
            hisotusSaah6.set(4, awal2.get(0));    
       }else{
           rowTm = new Row[2];                      
           Row hasilTm = new Row(6);
           
           int[] limitHisotusSaah = {60,60,60,60};
           int[] limitHisotusSaah6 = {60,60,60,60,60,60};
           for(int i=0;i<2;i++){
                rowTm[i] = new Row(4);                
           }
           int hs = total.get(7);
           rowTm[0].set(0, sawani * hs);
           rowTm[0] = rowTm[0].normalize(limitHisotusSaah, false, 4);    
           
           hs = total.get(6);
           rowTm[1].set(1, sawani * hs);
           rowTm[1] = rowTm[1].normalize(limitHisotusSaah, false, 4);
           
           Row hasil4 = new Row(4);
           hasil4 = hasil4.add(rowTm[0], limitHisotusSaah, false, 6);
           hasil4 = hasil4.add(rowTm[1], limitHisotusSaah, false, 6);
           
           hasilTm = new Row(6);
           for(int i=0;i<4;i++){
        	   hasilTm.set(2+i, hasil4.get(i));   
           }
           
           rowI = new Row(6);
           rowI.convertWith(awal2, 4);
           
           if(satarAtas>satarBawah){
                hisotusSaah6 = rowI.substract(hasilTm, limitHisotusSaah6, false, 6);    
           }else{
                hisotusSaah6 = rowI.add(hasilTm, limitHisotusSaah6, false, 6);   
           }           
       }
       //Log.w(log_tag, "Takdil Hosotus Saah");
       /************************ Takdil Alamah ****************************/
       
       int[] limitTakdilAlamah = {60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60};
       rowTm = new Row[6];   
       Row mukadal4 = new Row(4);       
       mukadal4 = albukdulMuaddal6.getPerFragment(2, 4);
       Row hisotusaah4 = new Row(4);
       hisotusaah4 = hisotusSaah6.getPerFragment(2, 4);
       
       int[] limitAlamah = {60,60,60,60,60,60,60,60,24,7};
     
       int index=6;
       rowTm = new Row[8];
       for(int k=0;k<8;k++) {
            rowTm[k] = new Row(10);    
       }     
        for(int j=0;j<4;j++){
            index=6;
            for(int i=0;i<4;i++){                          
                 int m = mukadal4.get(j) ;
                 int h = hisotusaah4.get(3-i);
                 int hsl = m * h;           
                 rowTm[i+j].set(index, hsl);
                 rowTm[i+j] = rowTm[i+j].normalize(limitAlamah, false, 12);           
                 index = index - 2;
            }
        }
        rowTm[0].move(1, true);
        rowTm[2].move(1, false);
        rowTm[3].move(2, false);        
        for(int i=0;i<4;i++){                                         
            rowTm[4+i].move(i+3, false);
        }
       takdilAlamah10 = new Row(10);              
       for(int k=0;k<8;k++) {                      
            takdilAlamah10 = takdilAlamah10.add(rowTm[k], limitAlamah, false, 10);
       }    
       alamahJakarta6 = new Row(10);
       Row alalamah3  = total.getPerFragment(12, 3);
       Row alalamah6 = new Row(6);
       alalamah6.convertWith(alalamah3, 3);
       Row takdilAlamah6 = new Row(6);
        for(int i=0;i<6;i++){
            takdilAlamah6.set(i, takdilAlamah10.get(4+i));
        }
       int[] limitMuadalah ={60,60,60,60,24,7};
       alamahJakarta6 = alalamah6.substract(takdilAlamah6, limitMuadalah, false, 7, true);
       //Log.w(log_tag, "Takdil Alamah");
       /************************ sa'atul ijtima'/alamat ****************************/
       
        int kotaDeqiqoh =TableConstant.getInstance().getTable(8, kota, 0);
        int kotaSaah =TableConstant.getInstance().getTable(8, kota, 1);
        int flag_kota=TableConstant.getInstance().getTable(8, kota, 4);
       
        Row fadhlutThulain6 = new Row(6);
        fadhlutThulain6.set(3, kotaDeqiqoh);
        fadhlutThulain6.set(4, kotaSaah);
        
        saatulIjtima6 = new Row(6);
        if(flag_kota<0){
            saatulIjtima6 = alamahJakarta6.substract(fadhlutThulain6, limitMuadalah, false, 6, true);  
        }else{
            saatulIjtima6 = alamahJakarta6.add(fadhlutThulain6, limitMuadalah, false, 6);
        }
        //Log.w(log_tag, "sa'atul ijtima'/alamat");
        /************************ Adadus Sa'ah ****************************/        
        int[] limitAdadusSaah ={60,60,60,60,24};
        Row kurang5 = new Row(5);        
        kurang5.set(4, 24);
        Row saatulIjtima5 = new Row(5);        
        saatulIjtima5 = saatulIjtima6.getPerFragment(0, 5);        
        adadusSaah5 = kurang5.substract(saatulIjtima5, limitAdadusSaah, false, 5);

        /************************ Irtifa'ul Hilal ****************************/        
        
        int[] limitIrtifaulHilal ={60,60,60,60,60,60,60,60,60,24};
        rowTm = new Row[5];
        index = 0;
        kali = 30;
        for(int i=0;i<5;i++){
            rowTm[i] = new Row(10);
            rowTm[i].set(index, adadusSaah5.get(i) * kali);
            rowTm[i] = rowTm[i].normalize(limitIrtifaulHilal, false, 10);
            index+=1;
        }
        Row tmRow = new Row(10);
        for(int i=0;i<5;i++){            
            tmRow = tmRow.add(rowTm[i], limitIrtifaulHilal, false, 10);
        }
        irtifaulHilal6 = new Row(6);
        irtifaulHilal6 = tmRow.getPerFragment(0, 6);
        //Log.w(log_tag, "Irtifa'ul Hilal");
        /********************* muktsul hilal **********************/
        
        rowTm = new Row[7];
        kali = 4;
        index = 0;        
        int[] limitMuktsulHilal ={60,60,60,60,60,60,60,60,60,60,60,60};
        for(int i=0;i<6;i++){
            rowTm[i] = new Row(12);
            rowTm[i].set(index, irtifaulHilal6.get(i) * kali);
            rowTm[i] = rowTm[i].normalize(limitMuktsulHilal, false, 10);
            index+=1;
        }
        tmRow = new Row(12);
        for(int i=0;i<6;i++){            
            tmRow = tmRow.add(rowTm[i], limitMuktsulHilal, false, 10);
        }
        muktsulHilal7 = new Row(7);
        muktsulHilal7 = tmRow.getPerFragment(0, 7);
        //Log.w(log_tag, "muktsul hilal");
        /********************* convert to string **********************/
        
        int thilal1=irtifaulHilal6.get(5);
        int thilal2=irtifaulHilal6.get(4);
        int hari=saatulIjtima6.get(5);
        if(thilal2<2 || (thilal2==2 && thilal1<30)){
            hari+=2;                
        }else if(thilal2>2 || (thilal2==2 && thilal1>=30)){
            hari+=1;
        }
        if(hari>7){
            hari=hari%7;
        }
        String[] arrHari={"Ahad","Senin","Selasa","Rabu","Kamis","Jumat","Sabtu"};
        if(hari>0){
        	hari--;
        }else{
        	hari = arrHari.length - 1;
        }
        String hariName=arrHari[hari];            
        int hIjtima= saatulIjtima6.get(5);
        if(hIjtima>0){
        	hIjtima--;
        }else{
        	hIjtima = arrHari.length - 1;
        }
        String hariIjtimah=arrHari[hIjtima];            
        int menit=muktsulHilal7.get(KEY_DEQIQOH);
        int detik=muktsulHilal7.get(KEY_SAWANI);
        Record record=new Record();
        record.setHari(hariName);
        record.setTinggiHilal(thilal2+"'"+thilal1+"\"");
        record.setLamaHilal(menit+" menit "+detik+" detik");
        int jam=adadusSaah5.get(4);            
	        if(jam == 0){
	            jam = 18;
	        }
        record.setJam(jam+":"+adadusSaah5.get(3));
        record.setHariIjtimah(hariIjtimah);
        
        return record;
    }

	public Row getTotal() {
		return total;
	}

	public Row getTakdilKhosoh() {
		return takdilKhosoh;
	}

	public Row getTakdilMarkaz() {
		return takdilMarkaz;
	}

	public Row getAlbuduGhairuMuaddal3() {
		return albuduGhairuMuaddal3;
	}

	public Row getTakdilSyams6() {
		return takdilSyams6;
	}

	public Row getMuqowamusSyams6() {
		return muqowamusSyams6;
	}

	public Row getTakdilAyam() {
		return takdilAyam;
	}

	public Row getAlbukdulMuaddal6() {
		return albukdulMuaddal6;
	}

	public Row getTakdilAlamah10() {
		return takdilAlamah10;
	}

	public Row getAlamahJakarta6() {
		return alamahJakarta6;
	}

	public Row getSaatulIjtima6() {
		return saatulIjtima6;
	}

	public Row getAdadusSaah5() {
		return adadusSaah5;
	}

	public Row getIrtifaulHilal6() {
		return irtifaulHilal6;
	}

	public Row getMuktsulHilal7() {
		return muktsulHilal7;
	}
   
}
